package org.pizza.did.zookeeper;

import lombok.extern.slf4j.Slf4j;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;

/**
 * @author gaowei
 */
@Slf4j
public class ZookeeperHolder_ {

    private CuratorFramework client;

    private static final String NODE_NAME = "/IDMaker/ID-";

    private String address;

    private String port;

    public ZookeeperHolder_(String address, String port) {
        this.address = address;
        this.port = port;
    }

    /**
     * 每次机器启动时生成机器ID
     */
    public void init() {
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
        client = CuratorFrameworkFactory.newClient(this.address + ":" + this.port, retryPolicy);
        client.start();
    }

    /**
     * 生成临时顺序节点，从上图看最多客容纳1024台机器，因此需要对获取的节点序号进行模1024取余
     *
     * @return
     */
    public Long makeId() {
        String str = createSeqNode(NODE_NAME);
        if (null == str) {
            return null;
        }
        int index = str.lastIndexOf(NODE_NAME);
        if (index >= 0) {
            index += NODE_NAME.length();
            str = index <= str.length() ? str.substring(index) : "";
        }
        return Long.parseLong(str) % 1024;
    }

    /**
     * 使用zookeeper临时顺序节点特定生成递增机器ID
     *
     * @param pathPrefix
     * @return
     */
    private String createSeqNode(String pathPrefix) {
        try {
            // 创建一个 ZNode 顺序节点
            return client.create()
                    .creatingParentsIfNeeded()
                    //避免zookeeper的顺序节点暴增，可以删除创建的顺序节点
                    .withMode(CreateMode.EPHEMERAL_SEQUENTIAL)
                    .forPath(pathPrefix);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


}
